package com.bjpowernode.shop.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bjpowernode.shop.base.BaseCart;
import com.bjpowernode.shop.domain.*;
import com.bjpowernode.shop.feign.ProdServiceFeign;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/p/shopCart")
public class BasketController extends BaseCart {

    @Autowired
    private ProdServiceFeign prodServiceFeign;

    @GetMapping("/prodCount")
    public ResponseEntity<Integer> prodCount() {
        return ResponseEntity.ok(basketService.count(
                new LambdaQueryWrapper<Basket>().eq(
                        Basket::getUserId, getStringUserId()
                )
        ));
    }

    // 将List<Basket>集合数据转换为ShopVo对象
    @GetMapping("/info")
    public ResponseEntity<ShopVo> info() {
        // 查询当前用户的购物车总记录数
        int count = basketService.count(
                new LambdaQueryWrapper<Basket>()
                        .eq(Basket::getUserId, getStringUserId())
        );
        if (count > 50)
            throw new RuntimeException("购物车商品超出限制");
        
        /* 
        各店铺购物车的总集合ShopVo = List<ShopCart>
        店铺购物车对象ShopCart = 某店铺购物车中的商品条目的总集合List<CartItem>
        某店铺购物车中的某个商品条目CartItem
        ShopVo：[
            ShopCart1:{
                [CartItem1+满减+运费,CartItem2+满减+运费,CartItem3+满减+运费]
            }+三金额,
            ShopCart2:{
                [CartItem1+满减+运费,CartItem2+满减+运费,CartItem3+满减+运费]
            }+三金额
        ]
        Basket+Sku -> CartItem -> List<CartItem> -> +满减+运费=ShopCart[start] -> List<ShopCart> -> +三金额=ShopVo
        */

        // 1-1.创建返回值结果集，并封装
        ShopVo shopVo = new ShopVo();

        // 2-1.创建集合接收店铺购物车
        List<ShopCart> shopCartList = new ArrayList<>();

        // 3-1.查询购物车列表数据
        List<Basket> basketList = basketService.list(
                new LambdaQueryWrapper<Basket>()
                        .eq(Basket::getUserId, getStringUserId()));
        // 3-2.将购物车列表数据，按照店铺ID进行分组
        Map<Long, List<Basket>> shopidAndBasketListMap = basketList.stream()
                // 将集合数据按照ShopId进行分组，key是ShopId
                // value是该店铺购物车中商品的总集合List<Basket>/[List<CartItem>]
                .collect(Collectors.groupingBy(Basket::getShopId));


        // 5-2.整合SkuIdList，查询库存，用于补充购物车中的商品对象的字段数据
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
        // 5-3.远程调用查询sku数据
        List<Sku> skuList = prodServiceFeign.listBySkuId(skuIdList);
        if (CollectionUtils.isEmpty(skuList))
            throw new RuntimeException("商品列表数据查询异常");

        // 7-1-2.封装每个店铺的总金额的集合
        List<BigDecimal> totalMoneyList = new ArrayList<>();
        List<BigDecimal> finalMoneyList = new ArrayList<>();
        List<BigDecimal> subtractMoneyList = new ArrayList<>();

        // 3-3.遍历Map，组装CartItem
        shopidAndBasketListMap.forEach(
                (currShopId, currBasketList) -> {

                    // 6-3-3.创建封装当前店铺每项商品的金额
                    List<BigDecimal> itemPriceListOfCurrShopCart = new ArrayList<>();

                    // 6-1.创建当前店铺购物车
                    ShopCart currShopCart = new ShopCart();

                    // 5-5.为购物车准备装商品条目数据的集合
                    List<CartItem> currCartItemList = new ArrayList<>();

                    // 4-1.拆解 当前购物车商品表currBasketList 组装CartItem
                    currBasketList.forEach(
                            // 4-2.将当前店铺购物车中某个商品
                            currBasket -> {

                                // 5-4.查询当前商品的sku
                                List<Sku> currSkuList = skuList.stream()
                                        .filter(sku -> sku.getSkuId().equals(currBasket.getSkuId()))
                                        .collect(Collectors.toList());
                                Sku sku = currSkuList.get(0);

                                // 4-3.转为 CartItem //5-1.补充字段数据 //5-6.并封装到currCartItemList中
                                currCartItemList.add(
                                        CartItem.builder()
                                                .basketId(currBasket.getBasketId())
                                                .checked(true)
                                                .prodId(currBasket.getProdId())
                                                .prodName(sku.getProdName())
                                                .skuId(currBasket.getSkuId())
                                                .skuName(sku.getSkuName())
                                                .pic(sku.getPic())
                                                .price(sku.getPrice().toPlainString())
                                                .basketCount(currBasket.getBasketCount())
                                                .build()
                                );
                                // 6-3-2.+满减+运费=ShopCart, //单品总价存入集合中
                                itemPriceListOfCurrShopCart.add(
                                        sku.getPrice().multiply(new BigDecimal(currBasket.getBasketCount())));
                            }
                    );
                    // 6-2.封装购物车的商品条目集合
                    currShopCart.setShopCartItems(currCartItemList);

                    // 6-3-1.计算集合总价【当前店铺购物车总价】
                    BigDecimal currShopCartTotalPrice = itemPriceListOfCurrShopCart.stream().reduce(BigDecimal::add).get();

                    // 6-3-0.计算满减和运费
                    if (currShopCartTotalPrice.compareTo(new BigDecimal(99)) < 0) {
                        currShopCart.setYunfei(new BigDecimal(6));
                    }

                    // 2-2/7-.封装全店铺购物车列表
                    shopCartList.add(currShopCart);

                    // 7-1-1. 将单个店铺计算出的金额封装到集合当中
                    totalMoneyList.add(currShopCartTotalPrice.add(currShopCart.getYunfei()));
                    subtractMoneyList.add(currShopCart.getShopReduce());
                    finalMoneyList.add(currShopCartTotalPrice.subtract(currShopCart.getShopReduce()));
                }
        );
        // 7-0.计算总金额、实际金额(最终金额)、优惠金额
        BigDecimal finalMoney = finalMoneyList.stream().reduce(BigDecimal::add).get();
        BigDecimal totalMoney = totalMoneyList.stream().reduce(BigDecimal::add).get();
        BigDecimal subtractMoney = subtractMoneyList.stream().reduce(BigDecimal::add).get();

        // 1-2.封装结果集
        shopVo.setShopCartList(shopCartList);
        // 1-3.封装
        shopVo.setTotalMoney(totalMoney).setSubtractMoney(subtractMoney).setFinalMoney(finalMoney);
        // 1-4.返回结果
        return ResponseEntity.ok(shopVo);
    }

    // ---------------远程调用---------------
    @GetMapping("/getBasketListByIds")
    public List<Basket> getBasketListByIds(@RequestParam("basketIds") List<Long> basketIds) {
        return basketService.listByIds(basketIds);
    }

    @DeleteMapping("/clearCartList")
    public void clearCartList(@RequestParam("stringUserId") String stringUserId,
                              @RequestParam("skuIdList") List<Long> skuIdList) {
        basketService.remove(new LambdaQueryWrapper<Basket>()
                .eq(
                        StringUtils.isNotEmpty(stringUserId),Basket::getUserId,stringUserId
                ).in(
                        !CollectionUtils.isEmpty(skuIdList),Basket::getSkuId,skuIdList
                )
        );
    }
}


